from django.utils.functional import cached_property
from django.contrib.auth.models import User
from django.db import models

# Create your models here.此模型放置内容相关的数据
class Category(models.Model):
    STATUS_NORMAL=1
    STATUS_DELETE=0
    STATUS_ITEMS=(
        (STATUS_NORMAL,'正常'),
        (STATUS_DELETE,'删除'),
    )

    name=models.CharField(max_length=50,verbose_name="名称")
    status=models.PositiveIntegerField(default=STATUS_NORMAL,choices=STATUS_ITEMS,verbose_name="状态")
    is_nav=models.BooleanField(default=False,verbose_name="是否为导航")
    owner=models.ForeignKey(User,on_delete=models.CASCADE,verbose_name="作者")
    created_time=models.DateTimeField(auto_now_add=True,verbose_name="创建时间")
    @classmethod
    def get_navs(cls):

        categories=cls.objects.filter(status=cls.STATUS_NORMAL)
        # nav_categories=categories.filter(is_nav=True)
        # normal_categories=categories.filter(is_nav=False)
        nav_categories=[]
        normal_categories=[]
        for cate in categories:
            if cate.is_nav:
                nav_categories.append(cate)
            else:
                normal_categories.append(cate)

        return {
            'navs':nav_categories,
            'categories':normal_categories,
        }
    # def get_all(cls):
    #     return cls.objects.all()

    def __str__(self):
        return self.name
        #return '<Category:{}>'.format(self.name)
    class Meta:
        verbose_name='分类'
        verbose_name_plural='全部分类'

class Tag(models.Model):
    STATUS_NORMAL=1
    STATUS_DELETE=0
    STATUS_ITEMS=(
        (STATUS_NORMAL,'正常'),
        (STATUS_DELETE,'删除'),
    )

    name=models.CharField(max_length=50,verbose_name="名称")
    status=models.PositiveIntegerField(default=STATUS_NORMAL,choices=STATUS_ITEMS,verbose_name="状态")
    is_nav=models.BooleanField(default=False,verbose_name="是否为导航")
    owner=models.ForeignKey(User,on_delete=models.CASCADE,verbose_name="作者")
    created_time=models.DateTimeField(auto_now_add=True,verbose_name="创建时间")

    @classmethod
    def get_all(cls):
        return cls.objects.all()

    def __str__(self):
        return self.name
        #return '<Tag:{}>'.format(self.name)

    class Meta:
        verbose_name='标签'
        verbose_name_plural='全部标签'

class Post(models.Model):
    STATUS_NORMAL=1
    STATUS_DELETE=0
    STATUS_DRAFT=2
    STATUS_ITEM=(
        (STATUS_NORMAL,'正常'),
        (STATUS_DELETE,'删除'),
        (STATUS_DRAFT,'草稿'),
    )

    title=models.CharField(max_length=255,verbose_name="标题")
    desc=models.CharField(max_length=1024,blank=True,verbose_name="摘要")
    content=models.TextField(verbose_name="正文",help_text="正文必须为MarkDown格式")
    status=models.PositiveIntegerField(default=STATUS_NORMAL,choices=STATUS_ITEM,verbose_name="状态")
    category=models.ForeignKey(Category,on_delete=models.CASCADE,verbose_name="分类")
    tag=models.ManyToManyField(Tag,verbose_name="标签")
    owner=models.ForeignKey(User,on_delete=models.CASCADE,verbose_name="作者")
    created_time=models.DateTimeField(auto_now_add=True,verbose_name="创建时间")
    pv=models.PositiveIntegerField(default=1,verbose_name="访问量")
    uv=models.PositiveIntegerField(default=1,verbose_name="独立访客，统计1天内访问某站点的用户数(以cookie为依据)")

    def __str__(self):
        return self.title
        #return '<Post:{}>'.format(self.title)

    class Meta:
        verbose_name="文章"
        verbose_name_plural="全部文章"
        #根据id降序排序
        ordering=['-id']

    @staticmethod
    def get_by_tag(tag_id):
        try:
            tag=Tag.objects.get(id=tag_id)
        except Tag.DoesNotExist:
            tag=None
            post_list=[]
        else:
            post_list=tag.post_set.filter(status=Post.STATUS_NORMAL).select_related('owner','category')
        return post_list,tag

    @staticmethod
    def get_by_category(category_id):
        try:
            category=Category.objects.get(id=category_id)
        except Category.DoesNotExist:
            category=None
            post_list=[]
        else:
            post_list=category.post_set.filter(status=Post.STATUS_NORMAL).select_related('owner','category')
        return post_list,category

    @classmethod
    def latest_posts(cls):
        queryset=cls.objects.filter(status=cls.STATUS_NORMAL)
        return queryset

    @cached_property
    def tags(self):
        return ','.join(self.tag.values_list('name',flat=True))
    # 这里用到了 Django 提供的一个工具， cached_property ，它的作用是帮我们把返回的数据绑到实例上，不用每次访问都去
    # 执行 tags 函数中的代码。关于这点，你可以对比 Python 内置的 property。
    # 配置好这些后，RSS 和 sitemap 就配置完成了，下面来配置urls.py让其生效。
    
    @classmethod
    def hot_posts(cls):
        return cls.objects.filter(status=cls.STATUS_NORMAL).order_by('-pv')
    # def get_all(cls):
    #     return cls.objects.all()
        """
描述
@classmethod 修饰符对应的函数不需要实例化，不需要 self 参数，但第一个参数需要是表示自身类的 cls 参数，可以来调用类的属性，类的方法，实例化对象等。

语法
classmethod 语法：

classmethod
参数
无。
返回值
返回函数的类方法。

实例
以下实例展示了 classmethod 的使用方法：

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
class A(object):
    bar = 1
    def func1(self):  
        print ('foo') 
    @classmethod
    def func2(cls):
        print ('func2')
        print (cls.bar)
        cls().func1()   # 调用 foo 方法
 
A.func2()               # 不需要实例化
输出结果为：

func2
1
foo

=================

python staticmethod 返回函数的静态方法。

该方法不强制要求传递参数，如下声明一个静态方法：

class C(object):
    @staticmethod
    def f(arg1, arg2, ...):
        ...
以上实例声明了静态方法 f，从而可以实现实例化使用 C().f()，当然也可以不实例化调用该方法 C.f()。

函数语法
staticmethod(function)
参数说明：

无
实例
#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
class C(object):
    @staticmethod
    def f():
        print('runoob');
 
C.f();          # 静态方法无需实例化
cobj = C()
cobj.f()        # 也可以实例化后调用
以上实例输出结果为：

runoob
runoob

        """